package com.easyjava.builder;

import com.easyjava.bean.Constants;
import com.easyjava.bean.FieldInfo;
import com.easyjava.bean.TableInfo;
import com.easyjava.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedWriter;
import java.io.File;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;

/**
 * @ClassName BuildServiceImpl
 * @Date 2024/8/8  15:25
 **/
public class BuildServiceImpl {
    private static final Logger logger = LoggerFactory.getLogger(BuildService.class);

    public static void execute(TableInfo tableInfo) {


        File folder = new File(Constants.PATH_SERVICE_IMPL);
        if (!folder.exists()) {
            folder.mkdirs();
        }

        String interfaceName = tableInfo.getBeanName() +"Service";
        String className = tableInfo.getBeanName()+Constants.SUFFIX_SERVICE_IMPL;
        File file = new File(folder, className + ".java");


        try {
            OutputStream outputStream = Files.newOutputStream(file.toPath());
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "utf8");
            BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
            bufferedWriter.write("package " + Constants.PACKAGE_SERVICE_IMPL + ";");
            bufferedWriter.newLine();
            bufferedWriter.newLine();
            bufferedWriter.write("import org.springframework.stereotype.Service;");
            bufferedWriter.newLine();

            bufferedWriter.write("import "+ Constants.PACKAGE_SERVICE + "."+ interfaceName +";");
            bufferedWriter.newLine();
            bufferedWriter.write("import java.util.List;");
            bufferedWriter.newLine();
            String mapperName = tableInfo.getBeanName() + Constants.SUFFIX_MAPPER;
            String mapperBeanName = StringUtils.lowerCaseFirstLetter(mapperName);
            bufferedWriter.write("import " + Constants.PACKAGE_PO + "."+ tableInfo.getBeanName()+";");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_QUERY + "." +tableInfo.getBeanParamName() +";");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_VO + ".PaginationResultVO;");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_MAPPER + "." + mapperName + ";");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_ENUMS + ".PageSize;");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_QUERY + ".SimplePage;");
            bufferedWriter.write("import javax.annotation.Resource;");
            BuildComment.createClassComment(bufferedWriter, tableInfo.getComment() + "Service");
            bufferedWriter.write("@Service(\""+StringUtils.lowerCaseFirstLetter(interfaceName)+"\")");
            bufferedWriter.newLine();
            bufferedWriter.write("public class  " + className + " implements " +interfaceName+"{");
            bufferedWriter.newLine();
            bufferedWriter.write("\t@Resource");
            bufferedWriter.newLine();
            bufferedWriter.write("\tprivate " + mapperName + "<"+tableInfo.getBeanName()+","+tableInfo.getBeanParamName()+"> " + mapperBeanName + ";");
            bufferedWriter.newLine();
            BuildComment.createFieldComment(bufferedWriter,"根据条件查询列表");
            bufferedWriter.write("\tpublic List<" + tableInfo.getBeanName() +"> findListByParam("+ tableInfo.getBeanParamName() + " param){");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\treturn this." + mapperBeanName + ".selectList(param);");
            bufferedWriter.newLine();
            bufferedWriter.write("\t}");
            bufferedWriter.newLine();
            bufferedWriter.newLine();

            BuildComment.createFieldComment(bufferedWriter,"根据条件查询数量");
            bufferedWriter.write("\tpublic int findCountByParam" + "(" + tableInfo.getBeanParamName() + " query){");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\treturn this." + mapperBeanName + ".selectCount(query);");
            bufferedWriter.newLine();
            bufferedWriter.write("\t}");
            bufferedWriter.newLine();
            bufferedWriter.newLine();

            BuildComment.createFieldComment(bufferedWriter,"分页查询");
            bufferedWriter.write("\tpublic PaginationResultVO<"+tableInfo.getBeanName()+"> findListByPage(" + tableInfo.getBeanParamName()+ " param){");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\tint count = this.findCountByParam(param);");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\tint pageSize = param.getPageSize()==null?PageSize.SIZE15.getSize():param.getPageSize();");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\tSimplePage page = new SimplePage(param.getPageNo(),count,pageSize);");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\tparam.setSimplePage(page);");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\tList<ProductInfo> list = this.findListByParam(param);");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\tPaginationResultVO<"+tableInfo.getBeanName()+"> result = new PaginationResultVO(count,page.getPageSize(),page.getPageNo(),page.getPageTotal(),list);");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\treturn result;");
            bufferedWriter.newLine();
            bufferedWriter.write("\t}");
            bufferedWriter.newLine();
            bufferedWriter.newLine();

            BuildComment.createFieldComment(bufferedWriter,"新增");
            bufferedWriter.write("\tpublic int add("+tableInfo.getBeanName()+" bean){");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\treturn this."+mapperBeanName+".insert(bean);");
            bufferedWriter.newLine();
            bufferedWriter.write("\t}");
            bufferedWriter.newLine();
            bufferedWriter.newLine();


            BuildComment.createFieldComment(bufferedWriter,"批量新增");
            bufferedWriter.write("\tpublic int addBatch(List<"+tableInfo.getBeanName()+"> listBean){");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\tif(listBean == null || listBean.isEmpty()){");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\t\treturn 0;");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\t}");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\treturn this.productInfoMapper.insertBatch(listBean);");
            bufferedWriter.newLine();
            bufferedWriter.write("\t}");
            bufferedWriter.newLine();
            bufferedWriter.newLine();


            BuildComment.createFieldComment(bufferedWriter,"批量新增或修改");
            bufferedWriter.write("\tpublic int addOrUpdateBatch(List<"+tableInfo.getBeanName()+"> listBean){");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\tif(listBean == null || listBean.isEmpty()){");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\t\treturn 0;");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\t}");
            bufferedWriter.newLine();
            bufferedWriter.write("\t\treturn this.productInfoMapper.insertOrUpdateBatch(listBean);");
            bufferedWriter.newLine();
            bufferedWriter.write("\t}");
            bufferedWriter.newLine();
            bufferedWriter.newLine();


            for (Map.Entry<String, List<FieldInfo>> entry :  tableInfo.getKeyIndexMap().entrySet()) {
                List<FieldInfo> keyFieldInfoList = entry.getValue();
                int index = 0;
                StringBuilder methodName = new StringBuilder();
                StringBuilder methodParamsWithType = new StringBuilder();
                StringBuilder methodParams = new StringBuilder();
                for (FieldInfo fieldInfo : keyFieldInfoList) {
                    index++;
                    methodName.append(StringUtils.uperCaseFirstLetter(fieldInfo.getPropertyName()));
                    if (index < keyFieldInfoList.size()) {
                        methodName.append("And");
                    }
                    methodParamsWithType.append(fieldInfo.getJavaType() + " " + fieldInfo.getPropertyName());
                    methodParams.append(fieldInfo.getPropertyName());
                    if (index < keyFieldInfoList.size()) {
                        methodParamsWithType.append(",");
                        methodParams.append(",");
                    }
                }
                BuildComment.createFieldComment(bufferedWriter,"根据"+ methodName + "查询");
                bufferedWriter.write("\tpublic "+tableInfo.getBeanName() + " get"+ tableInfo.getBeanName() + "By" + methodName + "("+methodParamsWithType+"){");
                bufferedWriter.newLine();
                bufferedWriter.write("\t\treturn this." + mapperBeanName + ".select"+ tableInfo.getBeanName() + "By" + methodName + "(" + methodParams + ");");
                bufferedWriter.newLine();
                bufferedWriter.write("\t}");
                bufferedWriter.newLine();
                bufferedWriter.newLine();

                BuildComment.createFieldComment(bufferedWriter,"根据"+ methodName + "更新");
                bufferedWriter.write("\tpublic int update" + tableInfo.getBeanName() + "By" + methodName + "("+tableInfo.getBeanName() + " bean, " + methodParamsWithType + "){");
                bufferedWriter.newLine();
                bufferedWriter.write("\t\treturn this." + mapperBeanName + ".update"+ tableInfo.getBeanName()+ "By" + methodName + "(bean," + methodParams + ");");
                bufferedWriter.newLine();
                bufferedWriter.write("\t}");
                bufferedWriter.newLine();
                bufferedWriter.newLine();

                BuildComment.createFieldComment(bufferedWriter,"根据"+ methodName + "删除");
                bufferedWriter.write("\tpublic int delete" + tableInfo.getBeanName() + "By" + methodName + "(" + methodParamsWithType + "){");
                bufferedWriter.newLine();
                bufferedWriter.write("\t\treturn this." + mapperBeanName + ".delete"+ tableInfo.getBeanName()+ "By" + methodName + "(" + methodParams + ");");
                bufferedWriter.newLine();
                bufferedWriter.write("\t}");
                bufferedWriter.newLine();
                bufferedWriter.newLine();
            }

            bufferedWriter.write("}");
            bufferedWriter.flush();
        } catch (Exception e) {
            logger.error("创建serviceIml失败", e);
        }
    }
}
